<?php


namespace plugin\exportcenter\app\service;


class CsvExport
{
    private $header;
    private string $filename;

    public function __construct()
    {
        $this->filename = base_path() . '/public/' . date("YmdHis") . rand(11111, 99999) . '.csv';
        //设置utf-8 bom头
        $bom = pack('CCC', 0xef, 0xbb, 0xbf);
        file_put_contents($this->filename, $bom, FILE_APPEND);
    }

    public function setHeader($header)
    {
        $this->header = $header;
        $curHead = array_keys($this->header);
        $file = fopen($this->filename, 'a');
        fputcsv($file, $curHead); //写头部
        fclose($file);
    }

    function export($data)
    {
        $file = fopen($this->filename, 'a');
        if (count($data) > 0) {
            foreach ($data as $item) {
                $row = [];
                foreach ($this->header as $key => $v) {
                    $vv = $this->getItem($item, $v);
                    $vv = $this->replaceSpecialCharacters($vv);
                    $row[$v] = $vv;
                }
                if ($row) {
                    fputcsv($file, $row);
                }
            }
        }
        fclose($file);
    }

    /**
     * 过滤特殊字符
     * @param $value
     * @return string|string[]
     */
    protected function replaceSpecialCharacters($value)
    {
        //处理逗号
        if (str_contains($value, ',')) {
            $value = '"'.$value.'"';
        }
        $value = str_replace("\n", '', $value); //处理换行符
        return $value;
    }

    private function getItem($item, $k)
    {
        if (is_callable($k)) {
            return call_user_func($k, $item);
        }

        if (!str_contains($k, ".")) {
            return $item[$k] ?? "";
        }
        $keys = explode('.', $k);
        $cur = collect($item)->toArray();
        foreach ($keys as $key) {
            $cur = $cur[$key] ?? "";
        }
        return $cur;
    }

    function batchExport($data)
    {
        $file = fopen($this->filename, 'a');
        $arr = [];
        if (count($data) > 0) {
            foreach ($data as $item) {
                $row = [];
                foreach ($this->header as $key => $v) {
                    $vv = $this->getItem($item, $v);
                    $vv = $this->replaceSpecialCharacters($vv);
                    $row[] = $vv;
                }
                $arr[] = implode(',', $row);
            }
        }
        fwrite($file, implode("\n", $arr));
        fclose($file);
    }

    public function getPath()
    {
        return $this->filename;
    }
}